Shortest distance from all buildings¶
Time: O(KxMxN); Space: O(MxN); hard
You want to build a house on an empty land which reaches all buildings in the shortest amount of distance. You can only move up, down, left and right.
You are given a 2D grid of values 0, 1 or 2, where: * Each 0 marks an empty land which you can pass by freely. * Each 1 marks a building which you cannot pass through. * Each 2 marks an obstacle which you cannot pass through. Have you met this question in a real interview?
Example 1:
Input: [[1,0,2,0,1],[0,0,0,0,0],[0,0,1,0,0]]
Output: 7
Explanation:
In this example, there are three buildings at (0,0), (0,4), (2,2), and an obstacle at (0,2).
1 - 0 - 2 - 0 - 1
| | | | |
0 - 0 - 0 - 0 - 0
| | | | |
0 - 0 - 1 - 0 - 0
The point (1,2) is an ideal empty land to build a house, as the total travel distance of 3+3+1=7 is minimal.
So return 7.
Example 2:
Input: [[1,0],[0,0]]
Output: 1
In this example, there is one buildings at (0,0).
1 - 0
| |
0 - 0
The point (1,0) or (0,1) is an ideal empty land to build a house, as the total travel distance of 1 is minimal. So return 1.
[1]:
class Solution1(object):
def shortestDistance(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
def bfs(grid, dists, cnts, x, y):
dist, m, n = 0, len(grid), len(grid[0])
visited = [[False for _ in range(n)] for _ in range(m)]
pre_level = [(x, y)]
visited[x][y] = True
while pre_level:
dist += 1
cur_level = []
for i, j in pre_level:
for dir in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
I, J = i+dir[0], j+dir[1]
if 0 <= I < m and 0 <= J < n and grid[I][J] == 0 and not visited[I][J]:
cnts[I][J] += 1
dists[I][J] += dist
cur_level.append((I, J))
visited[I][J] = True
pre_level = cur_level
m, n, cnt = len(grid), len(grid[0]), 0
dists = [[0 for _ in range(n)] for _ in range(m)]
cnts = [[0 for _ in range(n)] for _ in range(m)]
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
cnt += 1
bfs(grid, dists, cnts, i, j)
shortest = float("inf")
for i in range(m):
for j in range(n):
if dists[i][j] < shortest and cnts[i][j] == cnt:
shortest = dists[i][j]
return shortest if shortest != float("inf") else -1
[2]:
s = Solution1()
grid = [
[1,0,2,0,1],
[0,0,0,0,0],
[0,0,1,0,0]
]
assert s.shortestDistance(grid) == 7